home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / motif / xmblur.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.6 KB  |  300 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* $Revision: 1.3 $ */
  18. /* compile: cc -o xmblur xmblur.c -lGLw -lGLU -lGL -lXm -lXt -lX11 */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <Xm/Form.h>
  22. #include <Xm/Frame.h>
  23. #include <GL/GLwMDrawA.h>
  24. #include <X11/keysym.h>
  25. #include <X11/Xutil.h>
  26. #include <GL/gl.h>
  27. #include <GL/glu.h>
  28. #include <GL/glx.h>
  29.  
  30. static int      snglBuf[] =
  31. {
  32.     GLX_RGBA,
  33.     GLX_ACCUM_RED_SIZE, 8,
  34.     GLX_ACCUM_GREEN_SIZE, 8,
  35.     GLX_ACCUM_BLUE_SIZE, 8,
  36.     None
  37. };
  38.  
  39. static int      dblBuf[] =
  40. {
  41.     GLX_RGBA,
  42.     GLX_DOUBLEBUFFER,
  43.     GLX_ACCUM_RED_SIZE, 8,
  44.     GLX_ACCUM_GREEN_SIZE, 8,
  45.     GLX_ACCUM_BLUE_SIZE, 8,
  46.     None
  47. };
  48.  
  49. static String   fallbackResources[] =
  50. {
  51.     "*title: OpenGL motion blur demo",
  52.     "*glxarea*width: 300", "*glxarea*height: 300",
  53.     "*frame*x: 20", "*frame*y: 20",
  54.     "*frame*topOffset: 20", "*frame*bottomOffset: 20",
  55.     "*frame*rightOffset: 20", "*frame*leftOffset: 20",
  56.     "*frame*shadowType: SHADOW_IN",
  57.     NULL
  58. };
  59.  
  60. GLfloat         angleX = 15.0, angleY = 12.0;
  61. GLboolean       doubleBuffer = GL_TRUE;
  62.  
  63. Display        *dpy;
  64. XtAppContext    app;
  65. Widget          toplevel, form, frame, glxarea;
  66. XVisualInfo    *visinfo;
  67. GLXContext      glxcontext;
  68. XFontStruct    *xfont;
  69. int             firstChar, lastChar;
  70. GLuint          fontBase;
  71. char           *status;
  72. GLboolean       doBlur;
  73. GLUquadricObj  *quadObj;
  74.  
  75. void
  76. setBlur(GLboolean blurMode)
  77. {
  78.     doBlur = blurMode;
  79.     if (doBlur) {
  80.     status = "Blur: enabled";
  81.         glClear(GL_ACCUM_BUFFER_BIT); /* blow away accumulation contents */
  82.     } else {
  83.     status = "Blur: disabled";
  84.     }
  85. }
  86.  
  87. void
  88. drawScene(void)
  89. {
  90.     glClear(GL_COLOR_BUFFER_BIT);
  91.     /*
  92.      * Draw the wireframe cylinder.
  93.      */
  94.     glColor3f(1.0, 0.0, 0.0);
  95.     glPushMatrix();
  96.     glRotatef(angleX, 1.0, 0.0, 0.0);
  97.     glRotatef(angleY, 0.0, 1.0, 0.0);
  98.     glCallList(1);
  99.     glPopMatrix();
  100.     /*
  101.      * Use accumulation buffer for motion blurring.
  102.      */
  103.     if (doBlur) {
  104.     /*
  105.      * Be careful not to overflow the accumulation buffer; GL_RETURN is
  106.      * the only accumulation buffer operation defined to do clamping.
  107.      * Don't assume GL_MULT or GL_ACCUM clamp.
  108.      */
  109.     glAccum(GL_MULT, 0.8);
  110.     glAccum(GL_ACCUM, 0.2);
  111.     /*
  112.      * Renormalize the return by multipling the accumulation buffer
  113.      * contents by 5.
  114.      */
  115.     glAccum(GL_RETURN, 5.0);
  116.     }
  117.     /*
  118.      * Print out instructions and blur mode.
  119.      */
  120. #define HELP1 "Push 's' to step frame"
  121. #define HELP2 "Push 'b' toggles blur"
  122.     glColor3f(1.0, 1.0, 0.0);
  123.     glRasterPos2i(-14, 13);
  124.     glCallLists(sizeof(HELP1) - 1, GL_UNSIGNED_BYTE, HELP1);
  125.     glColor3f(1.0, 1.0, 0.0);
  126.     glRasterPos2i(-14, 11);
  127.     glCallLists(sizeof(HELP2) - 1, GL_UNSIGNED_BYTE, HELP2);
  128.     glColor3f(0.0, 1.0, 0.0);
  129.     glRasterPos2i(-14, -14);
  130.     glCallLists(strlen(status), GL_UNSIGNED_BYTE, (unsigned char *) status);
  131.     /*
  132.      * Swap the buffer if we are double buffering.
  133.      */
  134.     if (doubleBuffer)
  135.     GLwDrawingAreaSwapBuffers(glxarea);
  136.     /*
  137.      * Finish to ensure we aren't buffering up too much work.
  138.      */
  139.     glFinish();            
  140. }
  141.  
  142. void
  143. input_callback(Widget w, XtPointer client_data, XtPointer call)
  144. {
  145.     char            buffer[31];
  146.     KeySym          keysym;
  147.     GLwDrawingAreaCallbackStruct *call_data;
  148.     XComposeStatus  composeStatus;
  149.  
  150.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  151.  
  152.     switch (call_data->event->type) {
  153.     case KeyPress:
  154.     XLookupString(&call_data->event->xkey, buffer,
  155.               30, &keysym, &composeStatus);
  156.     switch (keysym) {
  157.     case XK_Escape:
  158.         exit(0);
  159.         break;
  160.     case XK_B:
  161.     case XK_b:
  162.         setBlur(!doBlur);    /* toggle blur mode */
  163.         drawScene();
  164.         break;
  165.     case XK_S:
  166.     case XK_s:
  167.         angleX += 15.0;
  168.         angleY += 12.0;
  169.         if (angleX >= 360.0)
  170.         angleX = 0.0;
  171.         if (angleY >= 360.0)
  172.         angleY = 0.0;
  173.         drawScene();
  174.         break;
  175.     }
  176.     break;
  177.     }
  178. }
  179.  
  180. void
  181. resize_callback(Widget w, XtPointer client_data, XtPointer call)
  182. {
  183.     GLwDrawingAreaCallbackStruct *call_data;
  184.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  185.  
  186.     glViewport(0, 0, call_data->width, call_data->height);
  187. }
  188.  
  189. void
  190. expose_callback(Widget w, XtPointer client_data, XtPointer call)
  191. {
  192.     GLwDrawingAreaCallbackStruct *call_data;
  193.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  194.  
  195.     if (doBlur) {
  196.     /*
  197.      * Can't trust the contents of the accumulation buffer after
  198.      * an expose.  Note: this makes xmblur regenerate itself after
  199.      * an expose properly if blur is enabled.
  200.      */
  201.         glClear(GL_ACCUM_BUFFER_BIT);
  202.     }
  203.     drawScene();
  204. }
  205.  
  206. void
  207. init_callback(Widget w, XtPointer client_data, XtPointer call)
  208. {
  209.     XVisualInfo    *visinfo;
  210.  
  211.     XtVaGetValues(w, GLwNvisualInfo, &visinfo, NULL);
  212.     glxcontext = glXCreateContext(XtDisplay(w), visinfo,
  213.               /* no sharing */ 0, /* direct if possible */ GL_TRUE);
  214. }
  215.  
  216. main(int argc, char **argv)
  217. {
  218.     toplevel = XtAppInitialize(&app, "Glxwidget", NULL, 0, &argc, argv,
  219.                    fallbackResources, NULL, 0);
  220.     dpy = XtDisplay(toplevel);
  221.     form = XmCreateForm(toplevel, "form", NULL, 0);
  222.     XtManageChild(form);
  223.     frame = XmCreateFrame(form, "frame", NULL, 0);
  224.     XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
  225.       XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
  226.           XmNrightAttachment, XmATTACH_FORM, NULL);
  227.     XtManageChild(frame);
  228.     /*
  229.      * We find the XVisualInfo* we want for the GLwMDrawA widget _before_ we
  230.      * create the widget.  The alternative to this is specifying the OpenGL
  231.      * visual attributes as resources arguments when creating the widget but
  232.      * unfortunately, if a visual matching the attributes we specify does not
  233.      * exist, we get a fatal error message like:
  234.      * 
  235.      * Error: GLwMDrawingArea: requested visual not supported
  236.      * 
  237.      * By specifying exactly which XVisualInfo* we want, we avoid this problem,
  238.      * allowing us to fall back to another acceptable set of visual
  239.      * attirbutes (single buffered in this case) and print out our own more
  240.      * informative message if even the second visual selection fails.
  241.      */
  242.     visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
  243.     if (visinfo == NULL) {
  244.     visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
  245.     if (visinfo == NULL)
  246.         XtAppError(app, "no RGB visual with accumulation buffer");
  247.     doubleBuffer = GL_FALSE;
  248.     }
  249.     /*
  250.      * Load the desired font.
  251.      */
  252.     xfont = XLoadQueryFont(dpy, "9x15");
  253.     if (xfont == NULL) {
  254.     XtAppError(app, "no 9x15 font found");
  255.     }
  256.     glxarea = XtVaCreateManagedWidget("glxarea", glwMDrawingAreaWidgetClass,
  257.                       frame, GLwNvisualInfo, visinfo, NULL);
  258.     XtAddCallback(glxarea, GLwNginitCallback, init_callback, NULL);
  259.     XtAddCallback(glxarea, GLwNexposeCallback, expose_callback, NULL);
  260.     XtAddCallback(glxarea, GLwNresizeCallback, resize_callback, NULL);
  261.     XtAddCallback(glxarea, GLwNinputCallback, input_callback, NULL);
  262.     XtRealizeWidget(toplevel);
  263.     GLwDrawingAreaMakeCurrent(glxarea, glxcontext);
  264.     /*
  265.      * Make cylinder display list.
  266.      */
  267.     quadObj = gluNewQuadric();
  268.     gluQuadricDrawStyle(quadObj, GLU_LINE);
  269.     glNewList(1, GL_COMPILE);
  270.     gluCylinder(quadObj, 2.0, 5.0, 10.0, 10, 4);
  271.     glEndList();
  272.     /*
  273.      * Now the GLwNginitCallback has been called so the OpenGL context has
  274.      * been set up.  Now we can initialize the X font as a set of OpenGL
  275.      * display lists.
  276.      */
  277.     firstChar = xfont->min_char_or_byte2;
  278.     lastChar = xfont->max_char_or_byte2;
  279.     glXUseXFont(xfont->fid, firstChar, lastChar - firstChar + 1,
  280.         /* base display list of glyphs */ 2 
  281.         /* since 1 is used for the cylinder */);
  282.     glListBase(2 - firstChar);
  283.     /*
  284.      * Initialize OpenGL state.
  285.      */
  286.     glViewport(0, 0, 300, 300);    /* XXX work around Reality Engine bug */
  287.     glClearColor(0.0, 0.0, 0.0, 0.0);
  288.     glClearAccum(0.0, 0.0, 0.0, 0.0);
  289.     glMatrixMode(GL_PROJECTION);
  290.     glLoadIdentity();
  291.     glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
  292.     glMatrixMode(GL_MODELVIEW);
  293.     glLoadIdentity();
  294.     setBlur(GL_FALSE);
  295.     /*
  296.      * Start dispatching X events...
  297.      */
  298.     XtAppMainLoop(app);
  299. }
  300.